#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
卡密验证管理器
负责与服务器通信验证激活码
"""

import json
import os
import hashlib
import requests
import threading
import time
from datetime import datetime, timedelta
from typing import Dict, Optional, Tuple
import logging

logger = logging.getLogger(__name__)

class LicenseManager:
    """卡密验证管理器"""
    
    def __init__(self):
        self.server_url = "http://localhost:3000"
        self.license_file = "license.json"
        self.license_data = None
        self.machine_id = self.generate_machine_id()
        self.verification_thread = None
        self.stop_verification = False
        
    def generate_machine_id(self) -> str:
        """生成机器唯一标识"""
        import platform
        import uuid
        
        # 获取系统信息
        system_info = [
            platform.node(),  # 主机名
            platform.machine(),  # 机器类型
            platform.processor(),  # 处理器
            str(uuid.getnode()),  # MAC地址
        ]
        
        # 组合信息并生成哈希
        machine_string = "|".join(system_info)
        return hashlib.md5(machine_string.encode()).hexdigest()
    
    def load_license_data(self) -> Optional[Dict]:
        """加载本地许可证数据"""
        if os.path.exists(self.license_file):
            try:
                with open(self.license_file, 'r', encoding='utf-8') as f:
                    data = json.load(f)
                    return data
            except Exception as e:
                logger.error(f"加载许可证文件失败: {e}")
        return None
    
    def save_license_data(self, data: Dict) -> bool:
        """保存许可证数据到本地"""
        try:
            with open(self.license_file, 'w', encoding='utf-8') as f:
                json.dump(data, f, ensure_ascii=False, indent=2)
            return True
        except Exception as e:
            logger.error(f"保存许可证文件失败: {e}")
            return False
    
    def verify_license_online(self, license_key: str) -> Tuple[bool, str, Dict]:
        """在线验证激活码"""
        try:
            response = requests.post(
                f"{self.server_url}/api/verify",
                json={
                    "license_key": license_key,
                    "machine_id": self.machine_id
                },
                timeout=10
            )
            
            if response.status_code == 200:
                result = response.json()
                if result.get('valid'):
                    # 验证成功，保存许可证信息
                    license_data = {
                        "license_key": license_key,
                        "machine_id": self.machine_id,
                        "expire_date": result.get('expire_date'),
                        "features": result.get('features', []),
                        "max_contacts": result.get('max_contacts', 1000),
                        "verified_at": datetime.now().isoformat()
                    }
                    self.save_license_data(license_data)
                    self.license_data = license_data
                    
                    return True, result.get('message', '验证成功'), license_data
                else:
                    return False, result.get('message', '验证失败'), {}
            else:
                return False, f"服务器错误: {response.status_code}", {}
                
        except requests.exceptions.ConnectionError:
            return False, "无法连接到验证服务器", {}
        except requests.exceptions.Timeout:
            return False, "验证请求超时", {}
        except Exception as e:
            return False, f"验证失败: {str(e)}", {}
    
    def is_license_valid(self) -> Tuple[bool, str]:
        """检查许可证是否有效"""
        # 加载本地许可证数据
        if not self.license_data:
            self.license_data = self.load_license_data()
        
        if not self.license_data:
            return False, "未找到许可证信息"
        
        # 检查是否过期
        try:
            expire_date = datetime.fromisoformat(self.license_data['expire_date'].replace('Z', '+00:00'))
            if datetime.now(expire_date.tzinfo) > expire_date:
                return False, "许可证已过期"
        except Exception as e:
            return False, f"许可证日期格式错误: {e}"
        
        # 检查机器绑定
        if self.license_data.get('machine_id') != self.machine_id:
            return False, "许可证已绑定其他设备"
        
        return True, "许可证有效"
    
    def start_periodic_verification(self, callback=None):
        """开始定期验证许可证"""
        if self.verification_thread and self.verification_thread.is_alive():
            return
        
        self.stop_verification = False
        
        def verification_worker():
            while not self.stop_verification:
                try:
                    is_valid, message = self.is_license_valid()
                    if not is_valid:
                        if callback:
                            callback(is_valid, message)
                        break
                    
                    # 每30秒检查一次
                    time.sleep(30)
                except Exception as e:
                    logger.error(f"定期验证出错: {e}")
                    time.sleep(30)
        
        self.verification_thread = threading.Thread(target=verification_worker, daemon=True)
        self.verification_thread.start()
    
    def stop_periodic_verification(self):
        """停止定期验证"""
        self.stop_verification = True
        if self.verification_thread:
            self.verification_thread.join(timeout=5)
    
    def clear_license(self):
        """清除许可证信息"""
        self.license_data = None
        if os.path.exists(self.license_file):
            try:
                os.remove(self.license_file)
            except Exception as e:
                logger.error(f"删除许可证文件失败: {e}")
    
    def get_license_info(self) -> Optional[Dict]:
        """获取许可证信息"""
        if not self.license_data:
            self.license_data = self.load_license_data()
        return self.license_data
    
    def test_server_connection(self) -> Tuple[bool, str]:
        """测试服务器连接"""
        try:
            response = requests.get(f"{self.server_url}/api/health", timeout=5)
            if response.status_code == 200:
                return True, "服务器连接正常"
            else:
                return False, f"服务器响应错误: {response.status_code}"
        except requests.exceptions.ConnectionError:
            return False, "无法连接到验证服务器"
        except requests.exceptions.Timeout:
            return False, "连接超时"
        except Exception as e:
            return False, f"连接测试失败: {str(e)}" 